# -*-coding:utf-8
# @Time :2022/8/9 16:01
# @Author :xiaoho945
# @Description:充值模块

import random
from time import sleep
from typing import Union, Any
from requests import JSONDecodeError
from common.util.configUtil.configUtil import ConfigUtil
from common.util.jsonUtl.jsonUtil import JsonUtil
from common.util.logUtil.logUtil import LoggerUtil
from common.util.mySqlUtil.mySqlPool import select_sql
from common.util.timeUtil.timeUtil import get_now_time
from common.util.requestsUtil.requestsUtil import RequestsUtil
from core.charge.chargeApi.Api import *

jsonUtil = JsonUtil()
config = ConfigUtil()
req = RequestsUtil()
logger = LoggerUtil(2)


def get_password(username) -> str:
    return select_sql(jsonUtil.read_sql("password").format(username), 2)[0][0]


def login():
    try:
        username = 13666666666
        loginParams = {"username": username, "password": get_password(username)}
        response = req.send_request("post", url=ApiCommon.LOGIN, params=loginParams)
        optPwd = response["data"]['userInfo']["optPwd"]
        token = response["data"]['userInfo']["token"]
        # return response
        return optPwd, token
    except JSONDecodeError as e:
        logger.error(f"login: {e}")


def get_loginUser_proid():
    """
        用户名，密码，项目id，集团id
    :return:
    """
    return select_sql(jsonUtil.read_sql("proId"), 2)[0]


def chargeApi(dbId, price, deviceNo, token) -> dict:
    try:
        if deviceNo.startswith("610"):
            virtualType = 1
        else:
            virtualType = 0
        params = {
            "aid": dbId,
            "price": price,
            "virtualType": virtualType,
            "token": token
        }
        response = req.send_request("post", url=ApiCharge.CUSTOMERCHARGE, params=params)
        return response
    except JSONDecodeError as e:
        logger.error(f"chargeApi: {e}")


def switchOrg(proid, token) -> dict:
    try:
        params = {
            "aid": proid,
            "type": 5,
            "token": token
        }
        response = req.send_request("post", url=ApiCharge.SWITCHORG, params=params)
        return response
    except JSONDecodeError as e:
        logger.error(f"switchOrg: {e}")


def get_menu(token) -> dict:
    params = {
        "type": 1,
        "token": token
    }
    response = req.send_request("post", url=ApiCommon.GETMENU, params=params)
    return response


def getBlanceLesszero(proid) -> Union[bool, Any]:
    """
    查找该项目下商户表余额小于0元的表
    """
    balanceLessZero = jsonUtil.read_sql("select_balanceLesszero").format(proid, proid)
    balanceLesszeroList = select_sql(balanceLessZero, 2)
    if isinstance(balanceLesszeroList, list):
        if len(balanceLesszeroList) == 0:
            return False
        else:
            return balanceLesszeroList
    else:
        return balanceLesszeroList


def get_random_payamount(payAmount):
    """
    返回随机的充值金额
    """
    selectRandomPayamountSql = jsonUtil.read_sql("select_random_payamount").format(abs(payAmount), abs(payAmount))
    return select_sql(selectRandomPayamountSql, 2)[0][0]


def recharge_data(balanceLesszeroList=None) -> list:
    rechargeDataList = []
    if isinstance(balanceLesszeroList, list):
        for i in balanceLesszeroList:
            if isinstance(i, list):
                # 余额
                balance = float(i[1])
                payAmount = get_random_payamount(balance)
                rechargeDataList.append([i[0], payAmount, i[2]])
            else:
                # 余额
                balance = float(balanceLesszeroList[1])
                payAmount = get_random_payamount(balance)
                rechargeDataList.append([balanceLesszeroList[0], payAmount, balanceLesszeroList[2]])
                break
    return rechargeDataList


def charge():
    chargeCount = 0
    chargeCountSuccess = 0
    chargeCountFail = 0
    chargeAmountSum = 0
    failInfoList = []
    try:
        optPwd, token = login()
        proInfo = get_loginUser_proid()
        proId = proInfo[0]
        proName = proInfo[1]
        print(f"充值项目:{proName}")
        logger.info(f"充值项目:{proName}")
        switchOrg(proId, token)
        get_menu(token)
        rechargeData = recharge_data(getBlanceLesszero(proId))
        nowTimehour = int(get_now_time(2))
        if nowTimehour >= 22 or nowTimehour <= 8:
            print(f"当前时间:{get_now_time(1)}---不在充值时间！")
            logger.debug(f"当前时间:{get_now_time(1)}---不在充值时间!")
        else:
            if isinstance(rechargeData, list) and len(rechargeData) > 0:
                for i in rechargeData:
                    response = chargeApi(i[0], i[1], i[2], token)
                    if response["success"] is True:
                        print(f"正在充值: {i[2]},充值金额--->   {i[1]}  ,充值结果:--->  {response['msg']}")
                        logger.info(f"正在充值: {i[2]},充值金额--->   {i[1]}  ,充值结果:--->  {response['msg']}")
                        chargeCountSuccess += 1
                        chargeAmountSum += i[1]
                        sleep(1)
                    else:
                        if response["code"] != 200:
                            chargeCountFail += 1
                            logger.error(f"表号{i[2]}: {response}")
                            failInfo = {i[2]: response['msg']}
                            failInfoList.append(failInfo)
                            print(f"正在充值: {i[2]},充值金额--->   {i[1]}   ,充值结果:--->  {response['msg']}")
                            logger.info(f"正在充值: {i[2]},充值金额--->   {i[1]}   ,充值结果:--->  {response['msg']}")
                    chargeCount += 1
                sleep(1)
            else:
                print("暂无欠费电表！")
                logger.info("暂无欠费电表！")
    except Exception as e:
        logger.error(f"charge: {e}")
        charge()
    finally:
        print(
            f"充值完成：\n  充值次数:{chargeCount}\n  充值金额:{chargeAmountSum}\n充值成功次数:{chargeCountSuccess}\n充值时间:{get_now_time(1)}\n"
            f"充值失败次数:{chargeCountFail},失败明细:{failInfoList}\n\n")
        logger.info(
            f"充值完成：\n  充值次数:{chargeCount}\n  充值金额:{chargeAmountSum}\n充值成功次数:{chargeCountSuccess}\n充值时间:{get_now_time(1)}\n"
            f"充值失败次数:{chargeCountFail},失败明细:{failInfoList}\n\n")


def charge_Task() -> None:
    try:
        # schedule.every(random.randint(5, 15)).minutes.do(charge).tag("charge_Task")
        # schedule.run_all()
        # while True:
        #     schedule.run_pending()
        while True:
            charge()
            randomTime = random.randint(1800, 10000)
            sleep(randomTime)
    except Exception as e:
        logger.error(f"charge_Task: {e}")


if __name__ == '__main__':
    charge()
    # print(login())
    # print(get_password(13666666666))
